package service

import (
	"context"
	"database/sql"
	"fx_swift_boss/api"
	"fx_swift_boss/internal/model"
	"fx_swift_boss/internal/temple"
	"fx_swift_boss/pkg/code"
	"fx_swift_boss/pkg/global"
	"fx_swift_boss/pkg/internalerrors"
	"fx_swift_boss/pkg/logger"
	"fx_swift_boss/pkg/mail"
	"fx_swift_boss/pkg/page"
	"github.com/gogf/gf/v2/database/gdb"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/shopspring/decimal"
	"github.com/spf13/cast"
	"sync"
)

type IfcGateAgentSrv interface {
	// 代理商详情
	GetIfcGateAgentDetails(ctx context.Context, account string) (*api.GetIfcGateAgentDetailsRes, error)
	// 代理商列表
	IfcGateAgentApplyReview(ctx context.Context, req *api.IfcGateAgentApplyReviewReq) (*page.Collection[*api.IfcGateAgentApplyReviewRes], error)
	// 资质审核操作
	OperatorIfcGateAgentReview(ctx context.Context, req *api.OperatorIfcGateAgentReviewReq) error
	//代理商资质审核列表
	IfcGateAgentApproval(ctx context.Context, req *api.IfcGateAgentApprovalReq) (*page.Collection[*api.IfcGateAgentApprovalRes], error)
	//boss端获取待审核代理商数
	GetAgentAuditNums(ctx context.Context) (int, error)
	GetMerChantAgentCompanyInfo(ctx context.Context) ([]*api.GetMerchantAgentCompanyInfoRes, error)
}
type ifcGateAgentSrv struct {
}

func NewIfcGateAgentSrv() IfcGateAgentSrv {
	return &ifcGateAgentSrv{}
}

// 获取所有代理商的companyName
func (m *ifcGateAgentSrv) GetMerChantAgentCompanyInfo(ctx context.Context) ([]*api.GetMerchantAgentCompanyInfoRes, error) {
	var (
		err    error
		list   []*model.IfcgateEnterpriseAccountApply
		result = make([]*api.GetMerchantAgentCompanyInfoRes, 0)
	)
	if err = global.GFDB.Ctx(ctx).Schema("fx").Model("ifcgate_enterprise_account_apply").
		Where("status='pass'").Scan(&list); err != nil {
		return nil, internalerrors.New(code.ErrUnknown, "数据查询异常")
	}
	for _, value := range list {
		result = append(result, &api.GetMerchantAgentCompanyInfoRes{
			Id:          cast.ToString(value.ID),
			CompanyName: value.CompanyName,
		})
	}
	return result, err
}

func (a *ifcGateAgentSrv) GetAgentAuditNums(ctx context.Context) (int, error) {
	var (
		err  error
		nums int
	)
	nums = 0
	count, err := global.GFDB.Schema("fx").Model("ifcgate_enterprise_account_apply").Where("status=? or status=?", "init", "refuse").Count()
	if err != nil {
		logger.SugarLogger.Error(err)
	}
	if count >= 0 {
		nums = count
	}
	return nums, err
}

// 代理商审核列表
func (a *ifcGateAgentSrv) IfcGateAgentApproval(ctx context.Context, req *api.IfcGateAgentApprovalReq) (*page.Collection[*api.IfcGateAgentApprovalRes], error) {
	var (
		err        error
		resultList []*api.IfcGateAgentApprovalRes
		total      int
	)

	collectionDto := &page.Collection[*api.IfcGateAgentApprovalRes]{}
	collectionDto.Page = req.Page
	collectionDto.PageSize = req.PageSize

	mod := global.GFDB.Ctx(ctx).Schema("fx").Model("ifcgate_enterprise_account_apply fea").
		LeftJoin("ifcgate_agent fa", "fea.account=fa.account").
		Fields("fea.account as agent_account,fea.company_name,fea.status,fea.refuse_reason,fa.email,fea.created_at")
	if len(req.CompanyName) > 0 {
		mod.Where("fea.company_name like ?", "%"+req.CompanyName+"%")
	}
	if len(req.Status) > 0 {
		mod.Where("fea.status=?", req.Status)
	}
	if len(req.SortFields) > 0 && len(req.SortMethod) > 0 {
		mod.Order("fea." + req.SortFields + " " + req.SortMethod)
	}
	mod.Where("fea.status !='draft' and fea.status !='pass'")
	mod.Limit(int(page.PageToOffset(req.Page, req.PageSize)), cast.ToInt(req.PageSize))
	err = mod.ScanAndCount(&resultList, &total, false)
	collectionDto.TotalPage = page.GetTotalPage(req.Page, req.PageSize, cast.ToInt64(total))

	if err != nil {
		return nil, internalerrors.New(code.ErrUnknown, "数据查询异常")
	}
	collectionDto.Total = cast.ToInt64(total)
	collectionDto.List = resultList
	return collectionDto, err
}

// 代理商列表
func (a *ifcGateAgentSrv) IfcGateAgentApplyReview(ctx context.Context, req *api.IfcGateAgentApplyReviewReq) (*page.Collection[*api.IfcGateAgentApplyReviewRes], error) {
	var (
		err        error
		resultList []*api.IfcGateAgentApplyReviewRes
		total      int
	)

	collectionDto := &page.Collection[*api.IfcGateAgentApplyReviewRes]{}
	collectionDto.Page = req.Page
	collectionDto.PageSize = req.PageSize

	db := global.GFDB.Ctx(ctx).Schema("fx")
	mod := db.Model("ifcgate_enterprise_account_apply fea").
		LeftJoin("ifcgate_agent fa", "fea.account=fa.account").
		LeftJoin("select a.agent_account,a.status from (select status,agent_account,created_at from fx.ifcgate_fee where fee_type='01') a left join (select max(created_at) as created_at,max(agent_account) as agent_account from ifcgate_fee where fee_type='01' group by agent_account) b on a.agent_account=b.agent_account and a.created_at=b.created_at where b.agent_account is not null", "fea.account=fee.agent_account").As("fee").
		Fields("fea.account as agent_account,fea.company_name,fea.status,fea.refuse_reason,fa.email,fea.created_at,if(fee.status is null,'',fee.status) as fee_status")
	if len(req.CompanyName) > 0 {
		mod.Where("fea.company_name like ?", "%"+req.CompanyName+"%")
	}
	if len(req.Email) > 0 {
		mod.Where("fa.email like ?", "%"+req.Email+"%")
	}
	mod.Where("fea.status='pass'")
	if len(req.SortFields) > 0 && len(req.SortMethod) > 0 {
		mod.Order("fea." + req.SortFields + " " + req.SortMethod)
	}

	mod.Limit(int(page.PageToOffset(req.Page, req.PageSize)), cast.ToInt(req.PageSize))
	err = mod.ScanAndCount(&resultList, &total, false)
	collectionDto.TotalPage = page.GetTotalPage(req.Page, req.PageSize, cast.ToInt64(total))

	if err != nil {
		return nil, internalerrors.New(code.ErrUnknown, "数据查询异常")
	}

	//循环获取代理商入网成功企业数、代理商分润余额
	type EnterpriseNum struct {
		Num          int    `json:"num"`
		AgentAccount string `json:"agent_account"`
	}
	type EnterpriseFeeNum struct {
		FeeNum       int    `json:"feeNum"`
		AgentAccount string `json:"agent_account"`
	}
	numObj := []EnterpriseNum{}
	if err = db.Model("ifcgate_company_user").
		Where("agent_account!='' and merchant_no!=''").
		Group("agent_account").
		Fields("count(1) as num,agent_account").Scan(&numObj); err != nil {
		logger.SugarLogger.Error(err)
	}

	feeNumObj := []EnterpriseFeeNum{}
	if err = db.Model("ifcgate_fee").
		Where("agent_account!='' and account!='' and fee_type='00'").
		Group("agent_account").
		Fields("count(1) as feeNum,agent_account").Scan(&feeNumObj); err != nil {
		logger.SugarLogger.Error(err)
	}
	//查询代理商分润金额
	result, err := NewCommissionSrv().AgentCommissionAccount(ctx)

	//循环设置入网企业数，手续费，分润金额
	var wg sync.WaitGroup
	if resultList != nil {
		for i := 0; i < len(resultList); i++ {
			//设置入网成功企业数
			wg.Add(1)
			go func(i int) {
				defer wg.Done()
				resultList[i].Nums = 0
				if numObj != nil {
					for _, numValue := range numObj {
						if resultList[i].AgentAccount == numValue.AgentAccount {
							resultList[i].Nums = numValue.Num
						}
					}
				}
			}(i)

			//查询下级企业是否以配置手续费
			wg.Add(1)
			go func(i int) {
				defer wg.Done()
				resultList[i].EnterpriseIsFees = "false"
				if feeNumObj != nil {

					for _, feeValue := range feeNumObj {
						if resultList[i].AgentAccount == feeValue.AgentAccount && feeValue.FeeNum > 0 {
							resultList[i].EnterpriseIsFees = "true"
						}
					}
				}
			}(i)
			//设置分润金额
			wg.Add(1)
			go func(i int) {
				defer wg.Done()
				if len(result) > 0 {
					for _, amountValue := range result {
						if resultList[i].AgentAccount == amountValue.Account {
							resultList[i].AgentCommissionList = amountValue.AgentCommissionAccountInfo
						}
					}
				}
			}(i)
		}
		//等待所有并发完成
		wg.Wait()
	}

	collectionDto.Total = cast.ToInt64(total)
	collectionDto.List = resultList
	return collectionDto, err
}

// 代理商详情
func (a *ifcGateAgentSrv) GetIfcGateAgentDetails(ctx context.Context, account string) (*api.GetIfcGateAgentDetailsRes, error) {
	type DbVo struct {
		Email          string          `json:"email"`
		Status         string          `json:"status"`
		CompanyName    string          `json:"company_name"`
		CompanyTime    string          `json:"company_time"`
		Image          string          `json:"image"`
		ContactPerson  string          `json:"contact_person"`
		Phone          string          `json:"phone"`
		CompanyAddress string          `json:"company_address"`
		RegisterCode   string          `json:"register_code"`
		CompanyType    string          `json:"company_type"`
		CountryCode    int64           `json:"country_code"`
		Fee            decimal.Decimal `json:"fee"`
		UpdatedAt      string          `json:"updated_at"`
	}
	var (
		err            error
		dbVo           *DbVo
		result         = &api.GetIfcGateAgentDetailsRes{}
		countryObj     *model.FxCountry
		companyTypeObj *model.FxCompanyType
	)
	if err = global.GFDB.Ctx(ctx).Schema("fx").Model("ifcgate_enterprise_account_apply fea").
		LeftJoin("ifcgate_agent fa", "fea.account=fa.account").
		Fields("fa.email,fea.status,fea.company_name,fea.company_time,"+
			"fea.image,fea.contact_person,fea.phone,fea.company_address,fea.register_code,fea.company_type,"+
			"fea.country_code,fea.updated_at").
		Where("fa.account=?", account).Scan(&dbVo); err != nil {
		logger.SugarLogger.Error(err)
		return nil, internalerrors.New(code.ErrUnknown, "查询异常")
	}

	if dbVo == nil {
		return nil, internalerrors.New(code.ErrUnknown, "帐号数据异常")
	}

	if err = global.GFDB.Schema("fx").Model("ifcgate_company_type").Where("id=?", dbVo.CompanyType).Scan(&companyTypeObj); err != nil {
		logger.SugarLogger.Error(err)
		return nil, internalerrors.New(code.ErrUnknown, "查询异常")
	}

	if err = global.GFDB.Schema("fx").Model("fx_country").Where("iso_country_code=?", dbVo.CountryCode).Scan(&countryObj); err != nil {
		logger.SugarLogger.Error(err)
		return nil, internalerrors.New(code.ErrUnknown, "查询异常")
	}

	if countryObj != nil {
		result.CountryName = api.NameInfo{
			ChineseName: countryObj.ChineseName,
			EnglishName: countryObj.EnglishName,
		}
	}
	result.Email = dbVo.Email
	result.Status = dbVo.Status
	result.CompanyName = dbVo.CompanyName
	result.CompanyTime = dbVo.CompanyTime
	result.Additional = dbVo.Image
	result.ContactPerson = dbVo.ContactPerson
	result.Phone = dbVo.Phone
	result.CompanyAddress = dbVo.CompanyAddress
	if companyTypeObj != nil {
		result.CompanyType = api.NameInfo{
			ChineseName: companyTypeObj.ChineseName,
			EnglishName: companyTypeObj.EnglishName,
		}
	}
	result.RegisterCode = dbVo.RegisterCode
	result.UpdatedAt = dbVo.UpdatedAt
	return result, err
}

// 资质审核操作
func (a *ifcGateAgentSrv) OperatorIfcGateAgentReview(ctx context.Context, req *api.OperatorIfcGateAgentReviewReq) error {
	var (
		err      error
		result   sql.Result
		rowsNums int64
		agentObj *model.IfcgateAgent
	)
	global.GFDB.Schema("fx").Model("ifcgate_agent").Where("account=?", req.AgentAccount).Scan(&agentObj)
	db := g.DB().Schema("fx")

	if req.OperatorStr == "pass" {
		// 更新状态
		err = db.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
			result, err = tx.Model("ifcgate_enterprise_account_apply").
				Data(g.Map{"status": req.OperatorStr, "refuse_reason": req.RefuseReason}).
				Where("account=?", req.AgentAccount).Update()
			if err != nil {
				logger.SugarLogger.Error(err)
				return internalerrors.New(code.ErrUnknown, "状态更新异常")
			}
			rowsNums, err = result.RowsAffected()
			if err != nil || rowsNums == 0 {
				logger.SugarLogger.Error(err)
				return internalerrors.New(code.ErrUnknown, "状态更新异常")
			}
			return nil
		})
		// 发送邮件
		go mail.SendMail(agentObj.Email, "", temple.IfcGateAgentSuccessHtml, global.ViperObj.GetString("email.register"))
	} else if req.OperatorStr == "refuse" {
		result, err = global.GFDB.Schema("fx").Ctx(ctx).Model("ifcgate_enterprise_account_apply").
			Data(g.Map{"status": req.OperatorStr, "refuse_reason": req.RefuseReason}).
			Where("account=?", req.AgentAccount).Update()
		if err != nil {
			logger.SugarLogger.Error(err)
			return internalerrors.New(code.ErrUnknown, "状态更新异常")
		}

		// 发送邮件
		go mail.SendMail(agentObj.Email, "", temple.IfcGateAgentFailHtml, global.ViperObj.GetString("email.register"))
	}
	return err
}
